using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Decav.Gatsb.Configuration;
using Decav.Gatsb.Application;
using Decav.Gatsb;
using Decav.Gatsb.Data;
using Decav.Reality;
using System.Net.Mail;
using Decav.Gatsb.Web;
using Decav.Security;
using System.IO;

public partial class EditProfile : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ((IMasterPageTemplate)Master).SelectedPage = MainMenuNavigationButton.MyProfile;
        _updatedPhoneNumber = false;
        serverStatusMsgDiv.Visible = false;
        serverErrorMsgDiv.Visible = false;
        SetupUserProfileImage();

        if (!IsPostBack)
            SetupForm();
    }

    private void SetupUserProfileImage()
    {
        profileImage.ImageId = GatsbApplication.Current.CurrentUser.Id;
        profileImage.Alt = GatsbApplication.Current.CurrentUser.Name.ToString();
        noProfileImageText.Visible = !profileImage.ImageExists;
    }

    private bool _updatedPhoneNumber;

    private void SetupForm()
    {
        Decav.Gatsb.User user = GatsbApplication.Current.CurrentUser;
        nameTextBox.Text = user.Name.ToString();
        mobileTelTextBox.Text = user.MobilePhoneNumber.ToString();
        mobileProviderDropdown.SetSelectedType(user.TelephoneServiceProvider);

        switch (UserProfile.Gender)
        {
            case Gender.Female:
                femaleGenderRadio.Checked = true;
                break;
            case Gender.Male:
                maleGenderRadio.Checked = true;
                break;

            case Gender.Unknown:
                maleGenderRadio.Checked = false;
                femaleGenderRadio.Checked = false;
                break;
        }

        aboutTextBox.Text = _profile.About;
        postalCodeTextBox.Text = user.PostalCode;

        // PRIVACY
        profileSlider.SelectedValue = user.ProfilePrivacy;
        locationSlider.SelectedValue = user.LocationPrivacy;
        postsSlider.SelectedValue = user.DefaultPostPrivacy;

        if (user.AlternateSmsAddress != EmailAddress.Empty)
        {
            alternateSmsCheck.Checked = true;
            alternateSmsTextBox.Text = user.AlternateSmsAddress.ToString();
            alternateSmsTextBox.Style[HtmlTextWriterStyle.Display] = "inline";
        }
        else
        {
            alternateSmsCheck.Checked = false;
            alternateSmsTextBox.Text = user.TelephoneServiceProvider.CreateSmsAddress(user.MobilePhoneNumber).ToString();
            alternateSmsTextBox.Style[HtmlTextWriterStyle.Display] = "none";
        }
    }

    private void SaveForm()
    {
        User user = GatsbApplication.Current.CurrentUser;

        user.Name = PersonName.Parse(nameTextBox.Text);

        PhoneNumber telNum = new PhoneNumber(mobileTelTextBox.Text);
        if (user.MobilePhoneNumber != telNum)
        {
            _updatedPhoneNumber = true;
            user.MobilePhoneNumber = telNum;
        }

        if (user.TelephoneServiceProvider.GetTypeString() != mobileProviderDropdown.SelectedType)
        {
            _updatedPhoneNumber = true;
            user.TelephoneServiceProvider = TelephoneServiceProvider.GetProvider(mobileProviderDropdown.SelectedType);
        }

        if (femaleGenderRadio.Checked)
            UserProfile.Gender = Gender.Female;
        else if (maleGenderRadio.Checked)
            UserProfile.Gender = Gender.Male;
        else
            UserProfile.Gender = Gender.Unknown;

        UserProfile.About = aboutTextBox.Text;
        user.PostalCode = postalCodeTextBox.Text;

        // PRIVACY
        user.ProfilePrivacy = profileSlider.SelectedValue;
        user.LocationPrivacy = locationSlider.SelectedValue;
        user.DefaultPostPrivacy = postsSlider.SelectedValue;

        if (alternateSmsCheck.Checked)
            user.AlternateSmsAddress = new EmailAddress(alternateSmsTextBox.Text);
        else
            user.AlternateSmsAddress = EmailAddress.Empty;

        using (IGatsbDataAdapter adapt = GatsbApplication.Current.GetDataAdapter())
            adapt.UpdateUserProfile(user, UserProfile);

        bool passwordUpdated = UpdatePassword();
        bool pictureUpdated = UpdateProfilePicture();

        // When a user updates their phone number, we need to revalidate their account.
        if (_updatedPhoneNumber)
            Response.Redirect("~/ValidatePhone.aspx");

        string statusString = "Your profile has been updated";

        if (passwordUpdated)
            statusString += " and your password has been changed";

        statusString += ".";

        if (pictureUpdated)
            statusString += "  You have also uploaded a new profile picture.";

        GatsbWebApplication.Current.SetStatusAndRedirect(statusString);
    }

    private bool UpdatePassword()
    {
        if (oldPasswordTextBox.Text.Length > 0 || newPasswordTextBox.Text.Length > 0)
        {
            if (newPasswordTextBox.Text != newPasswordVerifyTextBox.Text)
            {
                SetError("Your password was not updated because the password and confirmation did not match.");
                return false;
            }

            if (newPasswordTextBox.Text.Length < 5)
            {
                SetError("Your new password must be at least five characters in length.");
                return false;
            }

            using (IGatsbDataAdapter adapt = GatsbApplication.Current.GetDataAdapter())
            {
                bool updateSuccess = adapt.ChangeUserPassword(
                    HashedPassword.HashPassword(oldPasswordTextBox.Text),
                    HashedPassword.HashPassword(newPasswordTextBox.Text));

                if (!updateSuccess)
                {
                    SetError("Your password was not updated because your old password was not correct.");
                    return false;
                }
            }

            return true;
        }
        else
        {
            return false;
        }
    }

    private bool UpdateProfilePicture()
    {
        Guid userId = GatsbApplication.Current.CurrentUser.Id;
        string pathName = Path.Combine(GatsbConfigurationSection.Current.UserUploadedImagesFolder, userId.ToString());

        try
        {
            if (!pictureUploadBox.HasFile)
                return false;

            if (!VerifyProfilePictureExtension(Path.GetExtension(pictureUploadBox.FileName)))
            {
                SetError("The picture that you uploaded is not an image type we support.");
                return false;
            }

            // Delete the old file.
            if (File.Exists(pathName))
                File.Delete(pathName);

            // Save the picture.
            pictureUploadBox.SaveAs(pathName);

            // get all the cached image sizes and remove them from the cache.
            foreach (UserImageSize imgSize in Enum.GetValues(typeof(UserImageSize)))
            {
                string fileName = Path.GetFileName(GatsbApplication.Current.GetImageUrl(userId, imgSize));
                fileName = Path.Combine(GatsbConfigurationSection.Current.CachedUserUploadedImagesFolder, fileName);
                if (File.Exists(fileName))
                    File.Delete(fileName);
            }

            SetupUserProfileImage();
            return true;
        }
        catch (Exception ex)
        {
            GatsbApplication.Current.LogException(ex);
            SetError("An error occured while setting your profile picture.  Please try again.");
            return false;
        }
    }

    private bool VerifyProfilePictureExtension(string extension)
    {
        extension = extension.Replace(".", string.Empty);

        return (Array.IndexOf<string>(_supportedImageExtensions, extension.ToLower()) != -1);
    }

    private static string[] _supportedImageExtensions = new string[] { "jpg", "jpeg", "bmp", "png", "tif", "gif" };

    private bool CustomValidate()
    {
        PersonName name = PersonName.Empty;
        if (!PersonName.TryParse(nameTextBox.Text, out name))
        {
            SetError("Please give us your real name, including a first name and last name.  You may use initials for your last name.");
            return false;
        }

        if (new PhoneNumber(mobileTelTextBox.Text).ToString().Length != 10)
        {
            SetError("Please provide us with your 10 digit mobile phone number.  We will use this number to send you notifications and allow you to send us posts.");
            return false;
        }

        if (postalCodeTextBox.Text.Trim().Length != 5)
        {
            SetError("Please provide us with your postal code.  We will use this to find places near you.");
            return false;
        }

        if (alternateSmsCheck.Checked)
        {
            try
            {
                new EmailAddress(alternateSmsTextBox.Text);
            }
            catch (ArgumentException)
            {
                SetError("Your SMS email account could not be changed because the email address you supplied was not valid.");
                return false;
            }
        }

        return true;
    }

    private void SetError(string message)
    {
        serverErrorMsgDiv.InnerHtml = message;
        serverErrorMsgDiv.Visible = true;
    }

    private UserProfile _profile = null;

    public UserProfile UserProfile
    {
        get
        {
            if (_profile == null)
            {
                using (IGatsbDataAdapter adapt = GatsbApplication.Current.GetDataAdapter())
                    _profile = adapt.GetUserProfile(GatsbApplication.Current.CurrentUser.Id);
            }

            return _profile;
        }
    }

    protected void CancelButton_Click(object sender, EventArgs e)
    {
        Response.Redirect(GatsbConfigurationSection.Current.AuthenticatedUserDefaultPage, true);
    }

    protected void UpdateButton_Click(object sender, EventArgs e)
    {
        Page.Validate();
        if (!Page.IsValid)
            return;

        if (!CustomValidate())
            return;

        SaveForm();
    }
}
